iT邦幫忙

2021 iThome 鐵人賽

DAY 15
0
Modern Web

JavaScript學習日記系列 第 15

JavaScript學習日記 : Day15 - 原型與繼承(二)

  • 分享至 

  • xImage
  •  

F.prototype

我們可以使用new F()這樣的構造函數創建一個新object,如果F.prototype是一個object,那new操作符會使用這個object設定為新object的[[prototype]]。

這邊的prototype只是F這個構造函數的一個屬性。

let animal = {
  eats: true
};

function Cat(name) {
  this.name = name;
}

Cat.prototype = animal;

let cat = new Cat("White cat"); //  cat.__proto__ == animal

console.log( cat.eats ); // true

設置Cat.prototype = animal的字面意思是,當創建了new Cat時,會把創建的object的[[prototype]]指向animal。

F.prototype只有在new F時才會用到,如果在創建後,F.prototype有了變化(F.prototype = {anothoer object}),已經存在的obejct會保持舊有的繼承,但是之後創建的objetc會繼承新的。

默認的F.prototype, 構造器屬性

每個函數都有prototype屬性,即使提供它。默認的prototype是一個只有constructor屬性的object,屬性constructor指向函數自身。

function Cat() {}

/* default prototype
Cat.prototype = { constructor: Cat };
*/

可以檢查一下 :

function Cat() {}
// by default:
// Cat.prototype = { constructor: Cat }

console.log( Cat.prototype.constructor == Cat ); // true

所以如果我們什麼都不做,constructor屬性可以透過[[prototype]]繼承給所有cat使用:

function Cat() {}
// by default:
// Cat.prototype = { constructor: Cat }

let cat = new Cat(); // inherits from {constructor: Cat}

console.log(cat.constructor === Cat); // true (from prototype)

我們可以使用constructor屬性來創建一個新object。

function Cat(name) {
  this.name = name;
  alert(name);
}

let cat = new Cat("White cat");

let cat2 = new cat.constructor("Black cat");

當我們有一個object,但是不知道它使用了哪個構造器(例如它來自第三方library),並且我們需要一個類似的object,這時候這種方法就很方便。

但是這裏需要注意的是,JavaScript並不能確保正確的constructor函數值。constructor只是默認存在函數的prototype,一但我們主動把它替換掉,constructor就不存在了。 例如:

function Cat() {}
Cat.prototype = {
  jumps: true
};

let cat = new Cat();
console.log(cat.constructor === Cat); // false

因此為了確保正確的constructor,我們可以選擇添加/刪除屬性到默認的prototype,而不是將整個覆蓋:

function Cat() {}

Cat.prototype.jumps = true

或是手動重新創建constructor屬性:

Cat.prototype = {
  jumps: true,
  constructor: Cat
};

如此一來就能確保正確的constructor。


上一篇
JavaScript學習日記 : Day14 - 原型與繼承(一)
下一篇
JavaScript學習日記 : Day16 - Promise
系列文
JavaScript學習日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言